

#ifndef __BCD_DECOMPOSER_H__
#define __BCD_DECOMPOSER_H__

// #include "common/cgal_def.h"
#include "polygon2d.h"

namespace global_path_planner {
namespace ccpp {

class BcdDecomposer{
public:
    explicit BcdDecomposer(std::shared_ptr<Polygon2D>& poly2d);
    virtual ~BcdDecomposer() = default;

    // bcd分解
    std::vector<Polygon_2> getPolygonsForBcd(const PolygonWithHoles& polygon_in,
                                            const Direction_2& dir);

    // 判断PolygonWithHoles几何模型是不是Simple
    bool isStrictlySimple(const PolygonWithHoles &pwh);

    // 构造Simple PolygonWithHoles
    void simplifyPolygonWithHoles(PolygonWithHoles* pwh);

    // 多边形旋转方向
    PolygonWithHoles rotatePolygonWithHoles(const PolygonWithHoles& pwh,
                                            const Direction_2& dir);
    // 按照顺时针和逆时针排序
    void sortPolygonWithHoles(PolygonWithHoles* pwh);

    // 获取两条直线或者直线与段之间的交叉点
    std::vector<Point_2> getSegmentIntersections(const std::list<Segment_2>& L,
                                                const Line_2& l);

private:
    // 根据多边形顶点重构多边形
    void processEvent(const PolygonWithHoles& pwh, const VertexConstCirculator& v,
                    std::vector<VertexConstCirculator>* sorted_vertices,
                    std::vector<Point_2>* processed_vertices,
                    std::list<Segment_2>* L, std::list<Polygon_2>* open_polygons,
                    std::vector<Polygon_2>* closed_polygons);

    // 线段位于顶点左边
    void outEvent(Segment_2& e_lower, Segment_2& e_upper,
                std::vector<Point_2>& intersections,
                const PolygonWithHoles& pwh, const VertexConstCirculator& v,
                std::vector<VertexConstCirculator>* sorted_vertices,
                std::vector<Point_2>* processed_vertices,
                std::list<Segment_2>* L, std::list<Polygon_2>* open_polygons,
                std::vector<Polygon_2>* closed_polygons);
    
    // 线段位于顶点右边
    void inEvent(Segment_2& e_lower, Segment_2& e_upper,
                std::vector<Point_2>& intersections,
                const PolygonWithHoles& pwh, const VertexConstCirculator& v,
                std::vector<VertexConstCirculator>* sorted_vertices,
                std::vector<Point_2>* processed_vertices,
                std::list<Segment_2>* L, std::list<Polygon_2>* open_polygons,
                std::vector<Polygon_2>* closed_polygons);

    // 线段位于顶点中间
    void otherEvent(const VertexConstCirculator& v,
                std::vector<Point_2>* processed_vertices,
                std::vector<VertexConstCirculator>* sorted_vertices,
                std::list<Segment_2>* L, std::list<Polygon_2>* open_polygons);

    // 对多边形的顶点进行排序
    std::vector<VertexConstCirculator> sortXYPolygonWithHoles(const PolygonWithHoles& pwh);

    // 点与最外层多边形的关系
    bool outOfPWH(const PolygonWithHoles& pwh, const Point_2& p);

private:
    std::shared_ptr<Polygon2D> __polygon2d_Ptr;
};

}  // namespace ccpp
}  // namespace global_path_planner

#endif  // __BCD_DECOMPOSER_H__